/***************************************************************************
 * Copyright 2012-2013 TXT e-solutions SpA
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the contract ICT-257367.
 *
 * Authors:
 *      Cristoforo Seccia
 *
 * Contributors:
 *        Domenico Rotondi (TXT e-solutions SpA)
 **************************************************************************/
package it.txt.ens.schema.test;

import it.txt.access.capability.commons.signer.X509DocumentSigner;
import it.txt.access.capability.commons.signer.model.X509CertificateKeyValues;
import it.txt.access.capability.commons.signer.model.X509DocumentSignerInfo;
import it.txt.access.capability.commons.utils.XMLPrinter;
import it.txt.ens.schema.RequestType;
import it.txt.ens.schema.ResponseType;
import it.txt.ens.schema.factory.model.FailureResponseDetails;
import it.txt.ens.schema.factory.model.SuccessResponseDetails;
import it.txt.ens.schema.request.factory.ENSAuthorisationRequestFactory;
import it.txt.ens.schema.request.factory.ENSAuthorisationRequestFactoryImpl;
import it.txt.ens.schema.response.factory.ENSAuthorisationResponseFactory;
import it.txt.ens.schema.response.factory.ENSAuthorisationResponseFactoryImpl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 *
 * @author Cristoforo Seccia (TXT e-solutions SpA)
 */
public class ENSTester {

//    private static final String RESOURCE_ID = "amqp://services.acme.com/ENS?Namespace=Mirafiori%20Robots&Pattern=PLine1.Cell1.Robots.RB1";
//    private static final String CAPABILITY_RESOURCE = "/resources/capabilities/demoserver01_to_alice.xml";
//    private static final String KEYSTORE_RESOURCE = "/resources/keystores/capability_keystore.jks";
//    private static final String CAPABILITY_HASH =
//                "MAoGA1UEChMDVFhUMQwwCgYDVQQLEwNDUlMxDzANBgNVBAMTBkNSUy1DQTEPMA0" +
//                "GA1UEAxMGQ1JTLUNBMB4XDTExMDMyOTA4MTAwOVoXDTEyMDMyOTA4MjAwOVowgY" +
//                "MxCzAJBgNVBAYTAlVTMREwDwYDQQIEwhDb2xvcmFkbzEPMA0GA1UEBxMGRGVudm" +
//                "VyMREwDwYDVQQKEwhBY21lIEx0ZDEdMBsGA1UEBMB4XDTExMDA1UEBxMGRDQT1U";
    private static ENSAuthorisationResponseFactory RESPONSE_FACTORY;
    private static ENSAuthorisationRequestFactory REQUEST_FACTORY;

    public static void main(String[] args) throws Exception{

        RESPONSE_FACTORY = ENSAuthorisationResponseFactoryImpl.getInstance("../../../TXTAccess_BIN/Schemas");
        REQUEST_FACTORY = ENSAuthorisationRequestFactoryImpl.getInstance("../../../TXTAccess_BIN/Schemas");

        Document signedENSServiceRequestDoc = 
                ENSTester.testENSServiceRequestHashCapability();

        Element signedENSServiceRequestElement =
                signedENSServiceRequestDoc.getDocumentElement();

        Document signedENSServiceRequestDoc2 =
                ENSTester.testENSServiceRequestStreamCapability();

        Element signedENSServiceRequestElement2 =
                signedENSServiceRequestDoc2.getDocumentElement();

        Document signedENSServiceSuccessResponseDoc =
                ENSTester.testENSServiceSuccessResponse(
                signedENSServiceRequestDoc);

        Element signedENSServiceSuccessResponseElement =
                signedENSServiceSuccessResponseDoc.getDocumentElement();
        
        Document signedENSServiceFailureResponseDoc =
                ENSTester.testENSServiceFailureResponse(
                signedENSServiceRequestDoc);

        Element signedENSServiceFailureResponseElement =
                signedENSServiceFailureResponseDoc.getDocumentElement();
        
        XMLPrinter.logDocumentElement(
                signedENSServiceRequestElement,
                "Created ENS Service Request (Hash Capability)", false);

        XMLPrinter.logDocumentElement(
                signedENSServiceRequestElement2,
                "Created ENS Service Request (Stream Capability)", false);

        XMLPrinter.logDocumentElement(
                signedENSServiceSuccessResponseElement,
                "Created ENS Service Success Response", false);

        XMLPrinter.logDocumentElement(
                signedENSServiceFailureResponseElement,
                "Created ENS Service Failure Response", false);
    }

    public static Document testENSServiceRequestHashCapability() throws Exception{

        String resourceID = "amqp://services.acme.com/ENS?Namespace=Mirafiori%20Robots&Pattern=PLine1.Cell1.Robots.RB1";
        File keystoreDir = new File("D:\\TXTAccess-2.1.2\\Keystore\\capability_keystore.jks");
        String capabilityHash = 
                "MAoGA1UEChMDVFhUMQwwCgYDVQQLEwNDUlMxDzANBgNVBAMTBkNSUy1DQTEPMA0" +
                "GA1UEAxMGQ1JTLUNBMB4XDTExMDMyOTA4MTAwOVoXDTEyMDMyOTA4MjAwOVowgY" +
                "MxCzAJBgNVBAYTAlVTMREwDwYDQQIEwhDb2xvcmFkbzEPMA0GA1UEBxMGRGVudm" +
                "VyMREwDwYDVQQKEwhBY21lIEx0ZDEdMBsGA1UEBMB4XDTExMDA1UEBxMGRDQT1U";
        URI resourceIDUri = new URI(resourceID);
        String subjectID = "alice@acme.com";
        String operation = "Create";

        Calendar calendar = new GregorianCalendar(2011, 10, 24, 14, 30, 0);
        Date deadLine = calendar.getTime();

        RequestType requestType =
        REQUEST_FACTORY.create(resourceIDUri, subjectID, operation,
                deadLine, capabilityHash);
        
        X509DocumentSignerInfo model = new X509DocumentSignerInfo();
        model.setKeystorePath(keystoreDir.getCanonicalPath());
        model.setPrivateKeyPwd("sysmgr".toCharArray());
        model.setKeystorePwd("sysmgr".toCharArray());
        model.setSignerID(subjectID);
        
        X509CertificateKeyValues keyValues = X509DocumentSigner.getCertificateKeyValues(model);
        Document requestDoc = REQUEST_FACTORY.marshal(requestType);
        X509DocumentSigner.signXMLElement(requestDoc.getDocumentElement(), 
                keyValues, ENSAuthorisationRequestFactoryImpl.SIGN_DOCUMENT_AFTER_NODE);
        return requestDoc;
    }

    public static Document testENSServiceRequestStreamCapability() throws Exception{

        String resourceID = "amqp://services.acme.com/ENS?Namespace=Mirafiori%20Robots&Pattern=PLine1.Cell1.Robots.RB1";
        InputStream capabilityStream = new FileInputStream("D:\\TXTAccess-2.1.2\\Capabilities\\demoserver01_to_alice.xml");
        File keystoreDir = new File("D:\\TXTAccess-2.1.2\\Keystore\\capability_keystore.jks");        
        URI resourceIDUri = new URI(resourceID);
        String subjectID = "alice@acme.com";
        String operation = "Create";

        Calendar calendar = new GregorianCalendar(2011, 11, 24, 14, 30, 0);
        Date deadLine = calendar.getTime();

        RequestType requestType =
                REQUEST_FACTORY.create(resourceIDUri,
                subjectID, operation, deadLine, capabilityStream);
        
        X509DocumentSignerInfo model = new X509DocumentSignerInfo();
        model.setKeystorePath(keystoreDir.getCanonicalPath());
        model.setPrivateKeyPwd("sysmgr".toCharArray());
        model.setKeystorePwd("sysmgr".toCharArray());
        model.setSignerID(subjectID);

        X509CertificateKeyValues keyValues = X509DocumentSigner.getCertificateKeyValues(model);
        Document requestDoc = REQUEST_FACTORY.marshal(requestType);
        X509DocumentSigner.signXMLElement(requestDoc.getDocumentElement(),
                keyValues, ENSAuthorisationRequestFactoryImpl.SIGN_DOCUMENT_AFTER_NODE);
        return requestDoc;
    }

    public static Document testENSServiceSuccessResponse(Document signedENSServiceRequestDoc) throws Exception{

        File keystoreDir = new File("D:\\TXTAccess-2.1.2\\Keystore\\capability_keystore.jks");
        String signerID = "demoserver01@acme.com";

        RequestType requestType =
                REQUEST_FACTORY.unmarshal(
                new DOMSource(signedENSServiceRequestDoc));
        
        SuccessResponseDetails details = new SuccessResponseDetails();
        details.setBrokerHost("RABBITMQ-HV_01");
        details.setQueueName("txtQueue");
        details.setBrokerPort(5267);
        details.setSubjectID(requestType.getSubject().getSubjectID());
        details.setVirtualHost("/principal");
        details.setAccessToken("sysmgr123");
        details.setSesionToken("successResponseType_token");
        Calendar calendar = new GregorianCalendar(2011, 9, 24, 14, 30, 0);
        details.setSessionExpiration(calendar.getTime());
        details.setUseTLS(true);

        ResponseType responseType =
                RESPONSE_FACTORY.createSuccessResponse(
                requestType.getRequestID(), requestType.getTimeStamp(), details);

        X509DocumentSignerInfo model = new X509DocumentSignerInfo();
        model.setKeystorePath(keystoreDir.getCanonicalPath());
        model.setPrivateKeyPwd("sysmgr".toCharArray());
        model.setKeystorePwd("sysmgr".toCharArray());
        model.setSignerID(signerID);

        X509CertificateKeyValues keyValues = X509DocumentSigner.getCertificateKeyValues(model);
        Document responseDoc = RESPONSE_FACTORY.marshal(responseType);
        X509DocumentSigner.signXMLElement(responseDoc.getDocumentElement(),
                keyValues, ENSAuthorisationResponseFactory.SIGN_DOCUMENT_AFTER_NODE);
        return responseDoc;
    }

    public static Document testENSServiceFailureResponse(Document signedENSServiceRequestDoc) throws Exception{

        File keystoreDir = new File("D:\\TXTAccess-2.1.2\\Keystore\\capability_keystore.jks");
        String signerID = "demoserver01@acme.com";

        RequestType requestType =
                REQUEST_FACTORY.unmarshal(
                new DOMSource(signedENSServiceRequestDoc));

        FailureResponseDetails details = new FailureResponseDetails();
        details.setErrorReason("The subject specified in the request is invalid.");
        details.setErrorCode("DENIED01CF12");

        ResponseType responseType =
                RESPONSE_FACTORY.createFailureResponse(
                requestType.getRequestID(), requestType.getTimeStamp(), details);

        X509DocumentSignerInfo model = new X509DocumentSignerInfo();
        model.setKeystorePath(keystoreDir.getCanonicalPath());
        model.setPrivateKeyPwd("sysmgr".toCharArray());
        model.setKeystorePwd("sysmgr".toCharArray());
        model.setSignerID(signerID);

        X509CertificateKeyValues keyValues = X509DocumentSigner.getCertificateKeyValues(model);
        Document responseDoc = RESPONSE_FACTORY.marshal(responseType);
        X509DocumentSigner.signXMLElement(responseDoc.getDocumentElement(),
                keyValues, ENSAuthorisationResponseFactory.SIGN_DOCUMENT_AFTER_NODE);
        return responseDoc;
    }
}
